﻿#pragma once
#ifndef GAMEPANEL_H
#define GAMEPANEL_H

#include <QLabel>
#include <QMainWindow>
#include <QMap>

#include "buttongroup_1.h"
#include "cardpanel.h"

#include "gamecontrol.h"
#include "player.h"

QT_BEGIN_NAMESPACE
namespace Ui {
	class GamePanel;
}
QT_END_NAMESPACE

//牌桌逻辑
class GamePanel : public QMainWindow {
	Q_OBJECT

public:
	GamePanel(QWidget* parent = nullptr);
	~GamePanel();
	// 初始化游戏控制类信息
	void gameControlInit();
	// 更新分数面板的分数
	void updatePlayerScore();
	// 切割并存储图片
	void initCardMap();
	// 裁剪图片
	void cropImage(QPixmap& pix, int x, int y, Card& c);
	// 初始化游戏按钮组
	void initButtonsGroup();
	// 初始化玩家在窗口中的上下文环境
	void initPlayerContext();
	// 初始化游戏场景
	void initGameScene();
	// 处理游戏的状态
	void gameStatusPrecess(GameControl::GameStatus status);
	// 发牌
	void startDispatchCard();
	// 移动扑克牌
	void cardMoveStep(Player* player, int curPos);
	// 处理分发得到的扑克牌
	void disposeCard(Player* player, const Cards& cards);
	// 更新扑克牌在窗口中的显示
	void updatePlayerCards(Player* player);
	// 加载玩家头像
	QPixmap loadRoleImage(Player::Sex sex, Player::Direction direct, Player::Role role);

	// 定时器的处理动作
	void onDispatchCard();

protected:
	void paintEvent(QPaintEvent* ev);

private:
	enum CardAlign { Horizontal, Vertical };
	struct PlayerContext {
		// 1. 玩家扑克牌显示的区域
		QRect cardRect;
		// 2. 出牌的区域
		QRect playHandRect;
		// 3. 扑克牌的对齐方式(水平 or 垂直)
		CardAlign align;
		// 4. 扑克牌显示正面还是背面
		bool isFrontSide;
		// 5. 游戏过程中的提示信息, 比如: 不出
		QLabel* info;
		// 6. 玩家的头像
		QLabel* roleImg;
		// 7. 玩家刚打出的牌
		Cards lastCards;
	};

	Ui::GamePanel* ui;
	// 整个游戏的背景图
	QPixmap m_bkImage;
	// gamecontrol实例
	GameControl* m_gameCtl;
	// 存储四个玩家
	QVector<Player*> m_playerList;
	// 卡牌和卡牌窗口的map类
	QMap<Card, CardPanel*> m_cardMap;
	// 卡牌的大小
	QSize m_cardSize;
	// 单张卡牌的背面图
	QPixmap m_cardBackImg;
	// key等于玩家，value等于该玩家周边的环境
	QMap<Player*, PlayerContext> m_contextMap;
	// 发牌区的扑克牌
	CardPanel* m_baseCard;
	// 发牌过程中移动的扑克牌
	CardPanel* m_moveCard;
	// 发牌区的位置
	QPoint m_baseCardPos;
	// 枚举类型，记录游戏状态
	GameControl::GameStatus m_gameStatus;
	// 存储一个用于发牌的计时器
	QTimer* m_timer;
};
#endif  // GAMEPANEL_H
